package main

import (
	"clouddisk/internal/gate"
	"flag"
	"fmt"
	"log"
	"os"
	"strconv"
)

type Config struct {
	RegistHost  string // 服务发现地址
	BaseService string // 监控的根服务
	UserService string
	FileService string
	ListenPort  string
	SecretKey   string
}

func initConfig() *Config {
	defaultPort := "10001"
	cfg := &Config{
		RegistHost:  "localhost:2379",
		BaseService: "/service",
		UserService: "/user_service",
		FileService: "/file_service",
		ListenPort:  defaultPort,
	}

	// 首先从环境变量读取secretKey
	secretKey := os.Getenv("APP_SECRET_KEY")
	if secretKey == "" {
		log.Fatal("环境变量 APP_SECRET_KEY 未设置")
	}
	cfg.SecretKey = secretKey

	// 定义命令行参数绑定
	flag.StringVar(&cfg.RegistHost, "regist-host", cfg.RegistHost, "服务注册中心地址")
	flag.StringVar(&cfg.BaseService, "base-service", cfg.BaseService, "服务监控根目录")
	flag.StringVar(&cfg.UserService, "user-service", cfg.UserService, "用户服务名称")
	flag.StringVar(&cfg.FileService, "file-service", cfg.FileService, "文件服务名称")
	flag.StringVar(&cfg.ListenPort, "port", cfg.ListenPort, fmt.Sprintf("服务监听端口 (默认: %v)", defaultPort))

	// 自定义帮助信息
	flag.Usage = func() {
		fmt.Fprintf(flag.CommandLine.Output(), "网关服务启动程序\n\n")
		fmt.Fprintf(flag.CommandLine.Output(), "用法: %s [选项]\n\n", os.Args[0])
		fmt.Fprintln(flag.CommandLine.Output(), "选项:")
		flag.PrintDefaults()

		fmt.Fprintln(flag.CommandLine.Output(), "\n环境变量:")
		fmt.Fprintln(flag.CommandLine.Output(), "  APP_SECRET_KEY    JWT签名密钥(必须设置)")
		fmt.Fprintln(flag.CommandLine.Output(), "  APP_REGIST_HOST  注册中心地址")
		fmt.Fprintln(flag.CommandLine.Output(), "  APP_BASE_SERVICE 服务监控根目录")
		fmt.Fprintln(flag.CommandLine.Output(), "  APP_USER_SERVICE 用户服务名称")
		fmt.Fprintln(flag.CommandLine.Output(), "  APP_FILE_SERVICE 文件服务名称")
		fmt.Fprintln(flag.CommandLine.Output(), "  APP_PORT         监听端口")

		fmt.Fprintln(flag.CommandLine.Output(), "\n示例:")
		fmt.Fprintf(flag.CommandLine.Output(), "  export APP_SECRET_KEY=mysecretkey\n")
		fmt.Fprintf(flag.CommandLine.Output(), "  %s -port 8080\n", os.Args[0])
	}

	flag.Parse()

	// 配置文件读取

	// 最终配置验证
	if err := validateConfig(cfg); err != nil {
		fmt.Printf("配置错误: %v\n\n", err)
		flag.Usage()
		os.Exit(1)
	}

	return cfg
}

func validateConfig(cfg *Config) error {
	// 监听端口验证
	port, err := strconv.Atoi(cfg.ListenPort)
	if err != nil {
		return fmt.Errorf("无效的端口号: %s", cfg.ListenPort)
	}
	if port < 1 || port > 65535 {
		return fmt.Errorf("端口号必须在 1-65535 之间")
	}

	// 服务发现地址验证
	if cfg.RegistHost == "" {
		return fmt.Errorf("服务注册中心地址不能为空")
	}

	// 服务名称验证
	if cfg.BaseService == "" {
		return fmt.Errorf("服务监控根目录不能为空")
	}
	if cfg.UserService == "" {
		return fmt.Errorf("用户服务名称不能为空")
	}
	if cfg.FileService == "" {
		return fmt.Errorf("文件服务名称不能为空")
	}

	// JWT密钥验证
	if cfg.SecretKey == "" {
		return fmt.Errorf("JWT签名密钥不能为空")
	}
	if len(cfg.SecretKey) < 32 {
		return fmt.Errorf("JWT密钥长度至少32位")
	}

	return nil
}

func main() {
	log.SetFlags(log.Llongfile | log.Ltime)

	cfg := initConfig()

	server, err := gate.NewGateServerBuilder().
		WithServiceName(cfg.UserService, cfg.FileService).
		WithDiscoverObject(cfg.RegistHost, cfg.BaseService).
		WithSecretKey(cfg.SecretKey).Build()

	if err != nil {
		panic(err)
	}

	err = server.Serve(":" + cfg.ListenPort)
	if err != nil {
		panic(err)
	}
	log.Println("程序已退出")
}
